#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<math.h>

int atoi(const char *str)
{
    int sign,num=0;
    assert(str!=NULL);

    while(*str==' ')
        str++;

    if(*str=='-')
    {
        sign=-1;
        str++;
    }

    while(*str>='0' && *str<='9')
    {
        num=num*10+(*str-'0');
        str++;
    }

    if(sign<0)
        return sign*num;
    return num;
}

double atof(const char *str)
{
    double val,power;
    int sign;
    assert(str!=NULL);

    while(*str==' ')
        str++;

    sign=*str=='-'?-1:1;

    if(*str=='-' || *str=='+') str++;

    val=0;
    while(*str>='0' && *str<='9')
    {
        val=val*10+((*str)-'0');
        str++;
    }
    if(*str=='.')
        str++;
    power=1;

    while(*str>='0' && *str<='9')
    {
        val=val*10+((*str)-'0');
        power*=10;
        str++;
    }

    return sign*val/power;
}

char* itoa2(int val,char *buf,unsigned int redix)
{
    char *bufptr;
    char *firstdig;
    unsigned int digval;

    assert(buf!=NULL);
    bufptr=buf;
    if(val<0)
    {
        *bufptr++='-';
        val=(unsigned int)(-(int)val);
    }

    firstdig=bufptr;

    do
    {
        digval=val%redix;
        val=val/redix;
        if(digval>9)
            *bufptr++=(char)(digval-9+'a');
        else
            *bufptr++=(char)(digval+'0');
    }
    while(val>0);
    *bufptr--='\0';

    char temp;
    do
    {
        temp=*bufptr;
        *bufptr=*firstdig;
        *firstdig=temp;

        bufptr--;
        firstdig++;
    }
    while(firstdig<bufptr);

    return buf;
}

int strcmp(const char *src,const char *dst)
{
    int reg=0;
    if(src==dst)
        return 1;

    assert(src!=NULL);

    if(dst==NULL)
        return -1;

    while(!(reg=*(unsigned char*)src-*(unsigned char*)dst)&& *dst)
    {
        ++src,++dst;
    }

    if(reg<0)
        return reg=-1;
    else if(reg>0)
        return reg=1;
    return reg;
}


char* strcpy(char *dst,const char *src)
{
    char *strDst=dst;
    assert(src!=NULL);

    while((*dst++=*src++)!='\0');
    /*//?? must be NULL here? not sure~
    {
        NULL;
    }
    */
    return strDst;
}


void* memcpy(void *dst,const void* src,size_t count)
{
    char *pbTo=(char*)dst;
    char *pbFrom=(char*)src;

    assert(dst!=NULL && src!=NULL);
    assert(pbTo>= pbFrom + count || pbFrom>= pbTo+count);

    while(count-->0)
    {
        *pbTo++=*pbFrom++;
    }
    return dst;
}

void* memmove(void *dst,const void *src,size_t count)
{
    char *pbTo=(char*)dst;
    char *pbFrom=(char*)src;

    assert(dst!=NULL && src!=NULL);

    if(dst<=src || pbTo>=pbFrom +count)
    {
        while(count-->0)
        {
            *pbTo++=*pbFrom++;
        }
    }
    else
    {
        pbTo=pbTo+count-1;
        pbFrom=pbFrom+count-1;
        while(count-->0)
        {
            *pbTo--=*pbFrom--;
        }
    }
}

void* memset(void *buf,int c,size_t count)
{
    char *pvTo=(char*)buf;
    assert(buf!=NULL);

    while(count-->0)
    {
        *pvTo=(char)c;
    }
    return buf;
}

struct s_t
{
    int a;
    int b;
};

int main()
{
    char *s="-1876";
    assert(-1876==atoi(s));
    assert(abs(2.345-atof("2.345"))<0.0000001);
    //printf("%f",atof("2.345"));
    printf("%d\n",sizeof(int));
    printf("%d\n",sizeof(char));
    char s1[10];
    printf("%s\n",itoa2(12345,s1,10));
    assert(strcmp("nihao","nihao")==0);
    char s2[10];
    assert(strcmp("nihao",strcpy(s2,"nihao"))==0);

    struct s_t s_t1={5,1};
    struct s_t s_t2;
    memcpy(&s_t2,&s_t1,sizeof(struct s_t));
    assert(s_t2.a==5);
    printf("%d\n",s_t2.a);

    memset(&s_t2,0,sizeof(struct s_t));
    printf("%d\n",s_t2.a);
}
